Skip to content

fix(input): preserve native key lifecycle across routing - #2142

Merged
ogulcancelik merged 1 commit into
masterfrom
issue/2077-native-key-lifecycle
Aug 1, 2026
Merged

fix(input): preserve native key lifecycle across routing#2142
ogulcancelik merged 1 commit into
masterfrom
issue/2077-native-key-lifecycle

Conversation

@ogulcancelik

Copy link
Copy Markdown
Collaborator

Summary

  • introduce a canonical key event carrying semantic meaning, lifecycle phase, repeat count, generated text, and opaque source provenance
  • replace separate forwarded/suppressed key tracking with one lease state machine that preserves ownership across repeats, releases, pane changes, focus loss, and consumed terminal actions
  • preserve real Windows console records through routing and use them only at the compatible ConPTY destination boundary
  • keep synthesized input, text/IME, paste, VT framing, Kitty, modifyOtherKeys, API input, and non-Windows encoding on semantic paths
  • retain the synthesized Shift+Enter fallback for legacy Windows applications
  • harden protocol 19 input limits and Windows CI/probe coverage

Windows exposed the failure through Escape in #2077, but the underlying problem was shared input routing: Herdr mixed semantic keys, committed text, physical provenance, repeat lifecycle, and destination encoding in one representation. This separates those concerns instead of adding another Windows-only key workaround.

This supersedes #2081. The final implementation was built from Jonathan Liebig's original Windows work and credits him as co-author, then restructures it around the shared input model and lease state machine.

Refs #2077.

Validation

  • just check: 3,138 Rust tests, clippy, Windows cross-clippy, integration tests, and 93 maintenance tests
  • exact SHA on native Windows: 134 Windows-filtered tests, 22 client-transport tests, native pane-ownership test, and Windows binary build
  • exact SHA on native Windows: separate/grouped consumed repeats, consumed-to-forwarded ownership, popup/context suppression, and modal repeat isolation
  • real ReadConsoleInputW ConPTY probe covering grouped Escape press/repeat/release records
  • manual Windows dogfood covering Escape/Codex interruption, printable repeats/releases, pane switching while held, retained-selection Ctrl+C, Shift+Enter, AltGr, dead keys, paste, and normal Codex use
  • focused reviewer and simplifier passes completed with no remaining P1/P2 findings

Boundaries

This does not change raw pane send-text Escape behavior from #1929, Ctrl+Break signaling, terminal emulation, rendering, or pane layout. Protocol 19 remains required because protocol 18 shipped in preview.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ogulcancelik, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 129beee3-4676-4cb7-8f3f-4b67286f8eae

📥 Commits

Reviewing files that changed from the base of the PR and between 8599943 and a72702a.

📒 Files selected for processing (36)
  • docs/next/CHANGELOG.md
  • docs/next/api/herdr-api.schema.json
  • scripts/windows_check.ps1
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/app/api/panes.rs
  • src/app/input/clipboard.rs
  • src/app/input/copy_mode.rs
  • src/app/input/lease.rs
  • src/app/input/mod.rs
  • src/app/input/modal.rs
  • src/app/input/navigate.rs
  • src/app/input/terminal.rs
  • src/app/mod.rs
  • src/app/popup.rs
  • src/app/runtime.rs
  • src/app/state.rs
  • src/app/worktrees.rs
  • src/client/input.rs
  • src/client/input/windows_vti.rs
  • src/client/mod.rs
  • src/config/keybinds.rs
  • src/input/encode.rs
  • src/input/mod.rs
  • src/input/model.rs
  • src/input/parse.rs
  • src/pane/input.rs
  • src/pane/terminal.rs
  • src/platform/windows.rs
  • src/protocol/wire.rs
  • src/raw_input.rs
  • src/server/client_transport.rs
  • src/server/clients.rs
  • src/server/headless.rs
  • tests/api_ping.rs
  • tests/cli/sessions.rs
  • tests/support/mod.rs
📝 Walkthrough

Walkthrough

The change introduces protocol 19 input metadata, native Windows key-record handling, lease-based press/repeat/release routing, direct text commits, ConPTY fallback encoding, and expanded Windows and transport tests.

Changes

Windows input lifecycle

Layer / File(s) Summary
Input contracts and protocol metadata
src/input/*, src/protocol/wire.rs, src/raw_input.rs, src/client/input.rs, src/client/input/windows_vti.rs
Terminal keys and wire events now carry repeat counts, generated text, physical identity, and input-source metadata. Text input uses TextCommit.
Windows conversion and ConPTY encoding
src/client/input/windows_vti.rs, src/platform/windows.rs, src/pane/terminal.rs, scripts/windows_conpty_enhanced_input_probe.ps1
Native console records preserve Windows key data. ConPTY fallback encoding handles key-down, repeats, releases, and Shift+Enter. The probe validates native records and VT behavior.
Lease-based routing and target cleanup
src/app/input/lease.rs, src/app/mod.rs, src/app/runtime.rs, src/app/input/terminal.rs, src/app/popup.rs, src/app/worktrees.rs, src/app/input/*
Input leases associate presses, repeats, and releases with the original pane or popup target. Runtime shutdown and focus changes remove or release related leases.
Text commits, transport limits, and validation
src/app/input/mod.rs, src/server/*, tests/*, scripts/windows_check.ps1, docs/next/*
Text commits route directly to modal, popup, or terminal inputs. Structured input limits include expanded payloads. Protocol expectations and Windows test selection now use version 19 and native lifecycle coverage.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WindowsConsole
  participant ClientInput
  participant WireProtocol
  participant App
  participant InputLeaseTable
  participant PaneRuntime
  WindowsConsole->>ClientInput: Emit native key record
  ClientInput->>WireProtocol: Encode key, source, repeat count, and text
  WireProtocol->>App: Deliver structured input event
  App->>InputLeaseTable: Normalize press and plan repeat
  InputLeaseTable->>PaneRuntime: Forward press, repeat, or release to original pane
  PaneRuntime-->>App: Report delivery or runtime loss
  App->>InputLeaseTable: Remove lease after release or shutdown
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary change: preserving native key lifecycle across input routing.
Description check ✅ Passed The description directly explains the input lifecycle, lease state machine, Windows handling, protocol changes, and validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/2077-native-key-lifecycle

Comment @coderabbitai help to get the list of available commands.

@kangal-bot kangal-bot added the ai-review Trigger automated AI reviews for pull requests admitted by the PR gate label Aug 1, 2026
@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

Greptile Summary

The PR introduces a canonical input-event model and lease-based key lifecycle routing.

  • Preserves native Windows console records through routing to compatible ConPTY destinations.
  • Tracks presses, grouped repeats, releases, focus loss, pane changes, and consumed actions through one lease state machine.
  • Separates committed text from semantic keys and extends protocol 19 with repeat counts, generated text, and source provenance.
  • Expands Windows lifecycle tests, CI checks, and the native ConPTY probe.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/app/input/lease.rs Introduces the lease state machine that preserves ownership and repeat behavior across the complete key lifecycle.
src/app/runtime.rs Routes local key, text, focus, repeat, and release events through the new lease and committed-text paths.
src/protocol/wire.rs Bumps protocol 19 and extends structured client input with repeat counts, generated text, text commits, and source provenance.
src/client/input/windows_vti.rs Preserves native Windows input records while retaining semantic handling for synthesized and VT input.
src/app/input/mod.rs Adds dedicated committed-text handling while retaining the existing headless backpressure policy discussed in the withdrawn prior thread.
src/pane/terminal.rs Selects native Windows record delivery only at compatible terminal destinations and otherwise uses semantic encoding.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Client input] --> B{Input kind}
    B -->|Key| C[Canonical TerminalKey]
    B -->|Committed text| D[TextCommit path]
    B -->|Paste or mouse| E[Existing semantic path]
    C --> F[Input lease state machine]
    F -->|Consumed| G[Suppress or reprocess repeats]
    F -->|Forwarded| H[Retain destination ownership]
    H --> I{Destination supports native record?}
    I -->|Yes| J[ConPTY native console record]
    I -->|No| K[Semantic terminal encoding]
    D --> L[Active modal or terminal target]
Loading

Reviews (4): Last reviewed commit: "fix(input): preserve native key lifecycl..." | Re-trigger Greptile

Comment thread src/app/input/mod.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
src/server/headless.rs (1)

4547-4547: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a regression test for background text promotion.

RawInputEvent::Text(_) now promotes its source client to the foreground. The supplied tests cover key, focus, and mouse promotion, but do not cover this new branch. Add a test that sends ClientInputEvent::TextCommit from a background client and verifies foreground promotion and delivery to the focused target.

src/server/client_transport.rs (1)

1605-1641: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a test for mixed paste + non-paste overflow classification.

The new tests cover pure repeat-count overflow, generated_text overflow, and TextCommit overflow, but none exercises a batch that mixes an oversized Paste with a Key/TextCommit event. Given the classification hinges on input_bytes == 0 (see Line 434 comment), add a test that locks in the intended behavior for this mixed case.

src/protocol/wire.rs (1)

1103-1157: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document the frozen byte vector to help future protocol changes.

The exact encoded byte assertion freezes the protocol 19 input envelope. The comment states the intent, but the vector alone does not show which field produced each byte group. Add a short field-order note so a later field addition is easy to re-derive.

src/raw_input.rs (1)

68-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider attaching the flushed bytes to the text-commit key.

extract_one_event at Lines 768-770 attaches with_vt_bytes to plain UTF-8 keys. This flush path calls only with_text_commit(), so the key keeps KeySource::Synthesized. The range record still reports start and len, so no behavior breaks today. Attaching the bytes keeps provenance consistent across both paths.

♻️ Proposed change
-                    event: RawInputEvent::Key(key.with_text_commit()),
+                    event: RawInputEvent::Key(
+                        key.with_text_commit().with_vt_bytes(buffer.clone()),
+                    ),
scripts/windows_conpty_enhanced_input_probe.ps1 (1)

135-152: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make Send-NativeRecordAndObserve observe only new output.

The helper searches the whole pane buffer for the needle. It does not snapshot the pane text before sending. The two current call sites use distinct expected records, so they cannot alias today. If a later check sends a record that a previous check already produced, Wait-PaneText returns immediately on the stale line and reports a false pass.

Send-KeyAndObserve and Send-RawAndObserve already avoid this by capturing a $before value. Count occurrences and require an increase.

♻️ Proposed refactor to require a new occurrence
 function Send-NativeRecordAndObserve {
     param(
         [string] $PaneId,
         [string] $Text,
         [string] $ExpectedRecord
     )
+    $needle = "PROBE_RECORD:$ExpectedRecord"
+    $before = ([regex]::Matches((Read-Pane -PaneId $PaneId), [regex]::Escape($needle))).Count
     & $script:Exe pane send-text $PaneId $Text | Out-Null
     if ($LASTEXITCODE -ne 0) {
         throw "pane send-text failed with exit code $LASTEXITCODE"
     }
-    $needle = "PROBE_RECORD:$ExpectedRecord"
-    $paneText = Wait-PaneText -PaneId $PaneId -Needle $needle
+    $deadline = (Get-Date).AddSeconds(10)
+    do {
+        $paneText = Read-Pane -PaneId $PaneId
+        $after = ([regex]::Matches($paneText, [regex]::Escape($needle))).Count
+        if ($after -gt $before) {
+            break
+        }
+        Start-Sleep -Milliseconds 200
+    } while ((Get-Date) -lt $deadline)
     return [ordered]@{
         expected_record = $needle
-        delivered = $paneText.Contains($needle)
+        delivered = $after -gt $before
         pane = $paneText
     }
 }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 24cbd854-178b-46cb-aa41-ba5a6b5a1097

📥 Commits

Reviewing files that changed from the base of the PR and between 02fe7d7 and ebc9dc3.

📒 Files selected for processing (36)
  • docs/next/CHANGELOG.md
  • docs/next/api/herdr-api.schema.json
  • scripts/windows_check.ps1
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/app/api/panes.rs
  • src/app/input/clipboard.rs
  • src/app/input/copy_mode.rs
  • src/app/input/lease.rs
  • src/app/input/mod.rs
  • src/app/input/modal.rs
  • src/app/input/navigate.rs
  • src/app/input/terminal.rs
  • src/app/mod.rs
  • src/app/popup.rs
  • src/app/runtime.rs
  • src/app/state.rs
  • src/app/worktrees.rs
  • src/client/input.rs
  • src/client/input/windows_vti.rs
  • src/client/mod.rs
  • src/config/keybinds.rs
  • src/input/encode.rs
  • src/input/mod.rs
  • src/input/model.rs
  • src/input/parse.rs
  • src/pane/input.rs
  • src/pane/terminal.rs
  • src/platform/windows.rs
  • src/protocol/wire.rs
  • src/raw_input.rs
  • src/server/client_transport.rs
  • src/server/clients.rs
  • src/server/headless.rs
  • tests/api_ping.rs
  • tests/cli/sessions.rs
  • tests/support/mod.rs

Comment thread src/app/input/lease.rs
Comment thread src/client/input/windows_vti.rs Outdated
Comment thread src/pane/terminal.rs
Comment thread src/protocol/wire.rs
@ogulcancelik
ogulcancelik force-pushed the issue/2077-native-key-lifecycle branch from ebc9dc3 to 877f7fb Compare August 1, 2026 00:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9fd4ced-8d7f-474a-97de-22ff1130f530

📥 Commits

Reviewing files that changed from the base of the PR and between ebc9dc3 and 877f7fb.

📒 Files selected for processing (36)
  • docs/next/CHANGELOG.md
  • docs/next/api/herdr-api.schema.json
  • scripts/windows_check.ps1
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/app/api/panes.rs
  • src/app/input/clipboard.rs
  • src/app/input/copy_mode.rs
  • src/app/input/lease.rs
  • src/app/input/mod.rs
  • src/app/input/modal.rs
  • src/app/input/navigate.rs
  • src/app/input/terminal.rs
  • src/app/mod.rs
  • src/app/popup.rs
  • src/app/runtime.rs
  • src/app/state.rs
  • src/app/worktrees.rs
  • src/client/input.rs
  • src/client/input/windows_vti.rs
  • src/client/mod.rs
  • src/config/keybinds.rs
  • src/input/encode.rs
  • src/input/mod.rs
  • src/input/model.rs
  • src/input/parse.rs
  • src/pane/input.rs
  • src/pane/terminal.rs
  • src/platform/windows.rs
  • src/protocol/wire.rs
  • src/raw_input.rs
  • src/server/client_transport.rs
  • src/server/clients.rs
  • src/server/headless.rs
  • tests/api_ping.rs
  • tests/cli/sessions.rs
  • tests/support/mod.rs
🚧 Files skipped from review as they are similar to previous changes (34)
  • src/app/api/panes.rs
  • docs/next/api/herdr-api.schema.json
  • src/client/mod.rs
  • src/app/input/copy_mode.rs
  • src/app/popup.rs
  • tests/api_ping.rs
  • scripts/windows_check.ps1
  • src/input/encode.rs
  • src/input/parse.rs
  • src/pane/input.rs
  • tests/support/mod.rs
  • src/app/runtime.rs
  • tests/cli/sessions.rs
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/app/input/clipboard.rs
  • src/server/clients.rs
  • src/app/input/modal.rs
  • src/app/worktrees.rs
  • src/platform/windows.rs
  • src/input/mod.rs
  • src/server/client_transport.rs
  • src/app/state.rs
  • src/app/input/lease.rs
  • src/server/headless.rs
  • src/client/input.rs
  • src/app/input/mod.rs
  • src/input/model.rs
  • src/pane/terminal.rs
  • docs/next/CHANGELOG.md
  • src/config/keybinds.rs
  • src/app/input/terminal.rs
  • src/app/input/navigate.rs
  • src/client/input/windows_vti.rs
  • src/app/mod.rs

Comment thread src/raw_input.rs Outdated
@ogulcancelik
ogulcancelik force-pushed the issue/2077-native-key-lifecycle branch from 877f7fb to 8599943 Compare August 1, 2026 00:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/input/model.rs (1)

184-191: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

is_ascii_uppercase drops text commits for non-ASCII uppercase characters.

A key such as Char('É') with KeyModifiers::SHIFT falls into the second arm, which requires empty modifiers. The text commit is then skipped for that keystroke. Use char::is_uppercase to cover non-ASCII layouts.

♻️ Proposed change
-            KeyCode::Char(ch) if ch.is_ascii_uppercase() => {
+            KeyCode::Char(ch) if ch.is_uppercase() => {
                 self.modifiers == KeyModifiers::SHIFT || self.modifiers.is_empty()
             }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f8bc1bb-48b8-4882-827c-72f37cc286e7

📥 Commits

Reviewing files that changed from the base of the PR and between 877f7fb and 8599943.

📒 Files selected for processing (36)
  • docs/next/CHANGELOG.md
  • docs/next/api/herdr-api.schema.json
  • scripts/windows_check.ps1
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/app/api/panes.rs
  • src/app/input/clipboard.rs
  • src/app/input/copy_mode.rs
  • src/app/input/lease.rs
  • src/app/input/mod.rs
  • src/app/input/modal.rs
  • src/app/input/navigate.rs
  • src/app/input/terminal.rs
  • src/app/mod.rs
  • src/app/popup.rs
  • src/app/runtime.rs
  • src/app/state.rs
  • src/app/worktrees.rs
  • src/client/input.rs
  • src/client/input/windows_vti.rs
  • src/client/mod.rs
  • src/config/keybinds.rs
  • src/input/encode.rs
  • src/input/mod.rs
  • src/input/model.rs
  • src/input/parse.rs
  • src/pane/input.rs
  • src/pane/terminal.rs
  • src/platform/windows.rs
  • src/protocol/wire.rs
  • src/raw_input.rs
  • src/server/client_transport.rs
  • src/server/clients.rs
  • src/server/headless.rs
  • tests/api_ping.rs
  • tests/cli/sessions.rs
  • tests/support/mod.rs
🚧 Files skipped from review as they are similar to previous changes (35)
  • docs/next/CHANGELOG.md
  • tests/api_ping.rs
  • src/app/api/panes.rs
  • src/client/mod.rs
  • src/app/input/copy_mode.rs
  • tests/cli/sessions.rs
  • docs/next/api/herdr-api.schema.json
  • src/app/popup.rs
  • scripts/windows_check.ps1
  • src/input/mod.rs
  • src/platform/windows.rs
  • src/app/input/mod.rs
  • src/input/parse.rs
  • src/server/clients.rs
  • src/app/input/modal.rs
  • src/client/input.rs
  • tests/support/mod.rs
  • src/server/client_transport.rs
  • src/input/encode.rs
  • src/pane/input.rs
  • src/app/input/clipboard.rs
  • src/pane/terminal.rs
  • src/server/headless.rs
  • src/app/input/terminal.rs
  • src/config/keybinds.rs
  • src/raw_input.rs
  • src/app/runtime.rs
  • src/app/worktrees.rs
  • src/app/input/navigate.rs
  • src/app/state.rs
  • src/app/mod.rs
  • src/protocol/wire.rs
  • src/app/input/lease.rs
  • scripts/windows_conpty_enhanced_input_probe.ps1
  • src/client/input/windows_vti.rs

Comment thread src/input/model.rs
refs #2077

Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
@ogulcancelik
ogulcancelik force-pushed the issue/2077-native-key-lifecycle branch from 8599943 to a72702a Compare August 1, 2026 00:51
@ogulcancelik

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Pimpmuckl

Pimpmuckl commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

As requested some Windows tests:

Tested exact #2142 head 8599943a on native Windows.

Area Test Result Notes
Escape lifecycle Hold Escape, confirm repeats, then release
Escape in Codex UI Use Escape in /hooks and another modal or popup
Printable lifecycle Hold a printable key, then release
Focus loss Hold a printable key, move focus away from the Herdr terminal, then release
Overlapping keys Hold two printable keys and release them in reverse order
Pane ownership Hold a key, switch panes before release, then return to the original pane
Pane switching Switch panes normally, press Escape, then type immediately
Retained-selection Ctrl+C With copy_on_select = false, select text and hold Ctrl+C
Ctrl+C cleanup After the retained-selection test, press Ctrl+C again with no selection
Shift+Enter Test Shift+Enter and plain Enter separately
Modified keys Test Ctrl, Alt, and Shift combinations
AltGr Enter AltGr characters such as @, , or ³
Dead keys Enter accents and composed characters
Navigation Test Home, End, Insert, Delete, arrows, Page Up, and Page Down
Paste Compare single-line paste with direct Codex
Paste with LF Paste text containing internal LF line breaks
Paste with CRLF Paste text containing internal CRLF line breaks
Trailing line break Paste text ending in CRLF
Normal usage Use Codex normally across multiple panes TBD

Edit: Tested the remainders.

Only noteworthy issue I can think of is BMP emojis not working consistently. That is an upstream OpenConsole/ConPTY bug though, Microsoft fixed that for Windows Terminal but not yet for ConPTY. So clearly out of scope for herdr imo.

@ogulcancelik
ogulcancelik merged commit b76adc1 into master Aug 1, 2026
8 checks passed
@ogulcancelik

Copy link
Copy Markdown
Collaborator Author

@Pimpmuckl ty for all the help!

@ogulcancelik
ogulcancelik deleted the issue/2077-native-key-lifecycle branch August 1, 2026 01:42
abhijit-s pushed a commit to abhijit-s/herdr that referenced this pull request Aug 1, 2026
Range b411274..26a7bc8 (7 commits): windows semantic escape taps,
native key lifecycle rework (herdrdev#2142), remove experiments settings TUI,
bottom tab bar placement (herdrdev#2118), agentmd protocol update,
alternate-screen agent history read, packed sidebar worktree groups.

Protocol: source PROTOCOL_VERSION is 19 (upstream bumped 18->19 for the
incompatible ClientKeySource/TextCommit wire change). Stable published 17,
preview published 18; 19 is unpublished and ahead of both channels, so no
further bump. Test fixtures already expect protocol 19.

Conflict resolutions:
- config.rs / app/mod.rs / app/input/mod.rs: additive merges keeping fork
  features (StatusConfig, command_palette, pub(crate) modal) alongside
  upstream additions (TabBarPositionConfig, limit_snapshot_lines, lease mod).
- app/input/navigate.rs: preserved the fork's revert of non-us shifted
  keybindings (herdrdev#1876) - kept unmodified_digit_for_key and its call sites
  removed - while adopting upstream's &TerminalKey lifecycle signatures the
  merged call chain requires.
- config/keybinds.rs: adopted upstream's matched_index (&TerminalKey borrow
  required by indexed_navigation_action); kept the fork's herdrdev#1876 test
  deletions removed.
- app/input/mouse.rs: kept both fork tab-click tests and upstream's
  bottom-mode-bar test.
- ui.rs auto-merged: fork status_right strip coexists with upstream bottom
  tab bar placement.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Trigger automated AI reviews for pull requests admitted by the PR gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants